package com.nanjia.boot.common.excelhandler;

import cn.idev.excel.metadata.Head;
import cn.idev.excel.write.merge.AbstractMergeStrategy;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class ExcelCellMergeStrategy extends AbstractMergeStrategy {

    private List<Integer> exportFieldGroupCountList;
    private Integer targetColumnIndex;
    private Integer rowIndex;
    private Class<?> dtoClass;

    public ExcelCellMergeStrategy(Class<?> dtoClass, List<?> dataList) {
        this.dtoClass = dtoClass;
        this.targetColumnIndex = findMergeColumnIndex(dtoClass);
        this.exportFieldGroupCountList = getGroupCountList(dataList, targetColumnIndex);
    }

    /**
     * 通过反射找到被 @ExcelMergeColumn 注解的字段对应的列索引
     */
    private Integer findMergeColumnIndex(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            if (fields[i].isAnnotationPresent(ExcelMergeColumn.class)) {
                return i;
            }
        }
        throw new IllegalArgumentException("未找到被 @ExcelMergeColumn 注解的字段");
    }

    /**
     * 根据数据列表和目标列索引构建合并分组
     */
    private List<Integer> getGroupCountList(List<?> dataList, int columnIndex) {
        if (CollectionUtils.isEmpty(dataList)) {
            return new ArrayList<>();
        }
        List<Integer> groupCountList = new ArrayList<>();
        int count = 1;
        try {
            Field field = dtoClass.getDeclaredFields()[columnIndex];
            field.setAccessible(true);
            Object prev = field.get(dataList.get(0));
            for (int i = 1; i < dataList.size(); i++) {
                Object current = field.get(dataList.get(i));
                if (Objects.equals(current, prev)) {
                    count++;
                } else {
                    groupCountList.add(count);
                    count = 1;
                    prev = current;
                }
            }
            groupCountList.add(count);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("反射获取字段值失败", e);
        }
        return groupCountList;
    }

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if (rowIndex == null) {
            rowIndex = cell.getRowIndex();
        }
        if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == targetColumnIndex) {
            mergeGroupColumn(sheet);
        }
    }

    private void mergeGroupColumn(Sheet sheet) {
        int rowCount = rowIndex;
        for (Integer count : exportFieldGroupCountList) {
            if (count == 1) {
                rowCount += count;
                continue;
            }
            // 清空被合并区域的内容（保留第一个单元格）
            for (int i = rowCount + 1; i < rowCount + count; i++) {
                Row row = sheet.getRow(i);
                if (row != null) {
                    Cell cell = row.getCell(targetColumnIndex);
                    if (cell != null) {
                        cell.setCellValue("");
                    }
                }
            }
            // 合并单元格
            CellRangeAddress cellRangeAddress = new CellRangeAddress(
                    rowCount, rowCount + count - 1, targetColumnIndex, targetColumnIndex
            );
            sheet.addMergedRegionUnsafe(cellRangeAddress);
            rowCount += count;
        }
    }
}